using DL.AnimatorEvents;
using UnityEngine;

namespace DL.Combat.Base
{
    public abstract class CharacterCombatBase
    {
        protected AnimatorEvent AnimatorEvent;
        protected Transform Self;
        protected Animator Animator;
        
        protected Transform CurrentTarget;
        
        protected void AttackEvent()
        {
            // TriggerDamaged();
        }

        /// <summary>
        /// 触发伤害
        /// </summary>
        protected virtual void TriggerDamaged()
        {
        
        }

        /// <summary>
        /// 攻击动作检查
        /// </summary>
        public virtual bool ExecuteAttack_Pre()
        {
            return true;
        }

        /// <summary>
        /// 攻击动作执行
        /// </summary>
        public abstract void ExecuteAttackAction();

        /// <summary>
        /// 攻击输入
        /// </summary>
        public abstract void ActionInput();
        
        //通用  
        /// <summary>
        /// 扇形
        /// </summary>
        /// <param name="player">玩家位置</param>
        /// <param name="target">敌人位置</param>
        /// <param name="angle">攻击角度</param>
        /// <param name="radius">攻击半径</param>
        /// <returns></returns>
        public bool UmbrellaAttact(Transform player, Transform target, float angle, float radius)
        {
            //玩家指向敌人的方向向量
            Vector3 attackDir = target.position - player.position;
            //首先通过两个单位向量间的点乘Dot得到两个向量之间角度的余弦值
            //在通过Acos得到弧度
            //接下来通过弧度转角度Rad2Deg 的到两个向量之间的夹角
            //真正的夹角度数
            float realAngle = Mathf.Acos(Vector3.Dot(attackDir.normalized, player.forward)) * Mathf.Rad2Deg;
            //判断角度是否小于技能角度的一半
            //在使用向量的长度的平方来判断与半径平方的大小 使用平方运算比magnitude块很多 因为magnitude要使用勾股定理进行开方
            if (realAngle < angle * 0.5f && attackDir.sqrMagnitude < radius * radius)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 圆形
        /// </summary>
        /// <param name="player">玩家位置</param>
        /// <param name="target">目标位置</param>
        /// <param name="radius">攻击半径</param>
        /// <returns></returns>
        public bool CircleAttack(Transform player, Transform target, float radius)
        {
            //得到玩家与被攻击物体的距离
            float distance = Vector3.Distance(player.position, target.position);

            if (distance < radius)
            {
                //在半径范围内 
                return true;
            }

            return false;
        }

        /// <summary>
        /// 矩形
        /// </summary>
        /// <param name="player">玩家位置</param>
        /// <param name="target">目标位置</param>
        /// <param name="rectangleWide">矩形的宽度</param>
        /// <param name="rectangleHigh">矩形的高度</param>
        /// <returns></returns>
        public bool RectangleAttack(Transform player, Transform target, float rectangleWide, float rectangleHigh)
        {
            //得到玩家位置指向被攻击物体的方向向量
            Vector3 dirVector = target.position - player.position;
            //与玩家位置正前方做点乘 得到投影
            float forwardDistance = Vector3.Dot(dirVector, player.forward.normalized);
            if (forwardDistance > 0 && forwardDistance < rectangleHigh)
            {
                //此时在矩形的高度范围内
                //与玩家位置正右方标量继续做点乘得到投影
                float rightDistance = Vector3.Dot(dirVector, player.right.normalized);
                //绝对值小于矩形的宽度的一半
                if (Mathf.Abs(rightDistance) <= rectangleWide * 0.5f)
                {
                    return true;
                }
                return false;
            }
            return false;
        }

    }
}
